// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.logic;

import java.io.File;
import java.util.HashMap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.epc.common.util.RestHashMap;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.http.file.dto.BigFileType;
import com.x52im.rainbowchat.http.file.u.BigFileUploder;
import com.x52im.rainbowchat.http.file.u.ShortVideoUploader;

/**
 * 大文件信息相关的Http接口处理器实现类。
 * 
 * @author Jack Jiang
 * @since 4.3
 */
public class FileInfoProcessor implements SysActionConst, Processor
{
	public static DBShell db = new DBShell();
	
	/**
	 * 处理器的核心实现方法.<br>
	 * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
	 * action_id进行对应动作的处理，以完成本次操作请求.
	 * 
	 * @param job_dispatch_id 作业调度ID
	 * @param action_id 动作ID
	 * @param Object newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
	 * @param Object oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @param UserRoot user 包含该请求用户完整个人信息封装对象（该对象来自于成功登陆后存放于session中的值）
	 * @return 任意类型返回值
	 * @throws Exception
	 */
	@Override public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user)
			throws Exception
	{
		Object ret = null;
		String newDataJSON = (String)_newData;
		
		switch (job_dispatch_id)
		{	
			// 处理服务端对外提供的文件信息查询等
			case com.x52im.rainbowchat.http.logic.dto.JobDispatchConst.LOGIC_FILE_MGR:
				ret = maintainMgrFileJobDispatcher(action_id, newDataJSON, _oldData , user);
				break;
			default:
				throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
		}
		return ret;
	}
	
	/** 
	 * 维护文件信息查询等请求.
	 * 
	 * @param action_id 维护类型，SysConstant中的操作类型常量
	 * @param newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
	 * @param oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @param userName 操作者的用户名
	 * @return 返回给客户端的对象
	 */
	public String maintainMgrFileJobDispatcher(int action_id
			, Object newData, Object oldData, User user) throws Exception
	{
		switch (action_id)
		{
			// 【接口1015-23-7】获取指定md5码的大文件上传信息
			case ACTION_APPEND1:
			{	
				JSONObject nwObj = JSONObject.parseObject((String)newData);
				
				// 要查询的文件md5码（查询时确保是用小写）
				String fileMd5 = nwObj.getString("file_md5").toLowerCase();
				// 用户的uid
				String userUid = nwObj.getString("user_uid");
				// 文件类型（@since 4.4）
				String fileTypeStr = nwObj.getString("file_type");
				int fileType = BigFileType.FILE_TYPE_COMMON_BIG_FILE;
				if(!CommonUtils.isStringEmpty(fileTypeStr))
					fileType = CommonUtils.getIntValue(fileTypeStr, BigFileType.FILE_TYPE_COMMON_BIG_FILE);
				
				String retCode = "-1";
				int chunkCount = -1;
				
				// 首先：查询该文件信息是否已存在于missu_big_files表中，存在即表示它已经被上传，且上传完成
				// [说明]：本表的存在，是为了在文件数量庞大或文件被分布式存储等情况下，提供统一的文件信息检索能力，
				//       而不至于直接搜索文件存储目录看看文件存不存在这种方法（既低效，且方案也受限——因为文件被分
				//       布式存储或转储等情况，就没法查到信息了）。
				if(db.queryData("select 1 from missu_big_files where res_md5='"+fileMd5+"' and file_status=0").size()>0)
				{
					retCode = "1";   //* 1 表示该文件已经存在且已上传完成（无需再次上传）
				}
				// 其次：再看看此文件是否未被上传完成（或根本没有上传过）
				else
				{
					// 看看是否存在该文件的分块（存在分块则表示文件已被上传过，只是没有传完而已）
					File bigFileChunkSavedDir = null;
					
					if(fileType == BigFileType.FILE_TYPE_COMMON_BIG_FILE)
					{
						bigFileChunkSavedDir = new File(BigFileUploder.getChunckCommonBigFileDir(fileMd5, userUid));
					}
					else if(fileType == BigFileType.FILE_TYPE_SHORT_VIDEO)
					{
						bigFileChunkSavedDir = new File(ShortVideoUploader.getChunckShortVideoFileDir(fileMd5, userUid));
					}
					
					LoggerFactory.getLog().debug("[HTTP大文件信息查询] 要查询的文件分块临时目录："
							+bigFileChunkSavedDir.getAbsolutePath());
					
					if(bigFileChunkSavedDir.exists())
					{
						// 看看分块目录中已经上传了多少块（为>=0的整数，断点上传时分块数是从1开始编号的）
						chunkCount = bigFileChunkSavedDir.listFiles().length;
						retCode = "2";//* 2 表示该文件已经存在查未上传完成（此时chunkCount才有意义）
					}
					else
					{
						retCode = "0";//* 0 表示该文件不存在(未被上传过)
					}
				}
				
				// 返回结果
				RestHashMap<String, Object> ret = RestHashMap.n()
						.p("retCode", retCode)
						.p("chunkCount", chunkCount+"");
				
				return JSON.toJSONString(ret);
			}
			
			default:
				throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
		}
	}
}
